package hapi.send;

import hapi.ontology.HL7Ontology;
import jade.content.lang.sl.SLCodec;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.ThreadedBehaviourFactory;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.proto.SubscriptionInitiator;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class SendAgent extends Agent {

	private static final long serialVersionUID = 1L;
	volatile List<AID> providerList = new ArrayList<AID>();

	public void setup() {
		
		//System.out.println("[Send Agent: Setup init...]");
		// Register languages and ontologies
		getContentManager().registerLanguage(new SLCodec());
		getContentManager().registerOntology(HL7Ontology.getInstance());		
		refreshProviderList();
		
		//Threaded
		SendBehaviour b = new SendBehaviour(this,5000);
		ThreadedBehaviourFactory tbf = new ThreadedBehaviourFactory();
		addBehaviour(tbf.wrap(b));
		
	}

	private void refreshProviderList() {
		ServiceDescription sd = new ServiceDescription();
		sd.setType(HL7Ontology.SERVICE_PROVIDER);
		
		DFAgentDescription template = new DFAgentDescription();
		template.addServices(sd);
		
		ACLMessage subscribe = DFService.createSubscriptionMessage(this,
				this.getDefaultDF(), template, null);
		
		this.addBehaviour(new SubscriptionInitiator(this, subscribe) {
			private static final long serialVersionUID = 1L;

			public void handleInform(ACLMessage inform) {
				try {
					DFAgentDescription[] dfds = 
							DFService.decodeNotification(inform.getContent());
					for (int i = 0; i < dfds.length; ++i) {
						AID id = dfds[i].getName();
						Iterator it = dfds[i].getAllServices();
						if (it.hasNext()) {
							// Registration/modification
							if (!id.equals(myAgent.getAID())) {
								providerList.add(id);
							}
						} else {
							// Deregistration
							providerList.remove(id);
						}
					}
				} catch (FIPAException fe) {
					fe.printStackTrace();
				}
			}
		});
	}

	public List<AID> getProviderList() {
		return providerList;
	}

}
